package com.budwk.app.sqfwV2.component;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson.JSONObject;
import com.budwk.app.common.config.AppException;
import com.budwk.app.sqfw.constants.CommonConstants;
import com.budwk.app.sqfw.constants.DictConstants;
import com.budwk.app.sqfw.enums.DownLoadFileNameEnum;
import com.budwk.app.sqfw.enums.SupportBusinessTypeEnum;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfw.services.SqfwFormsummaryNewService;
import com.budwk.app.sqfwDoc.bo.SqfwExcelForSummaryBO;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.BaseTemplateExcelGenerator;
import com.budwk.app.sqfwDoc.codeGenerator.excelGenerate.SqfwExcelCreateCommonBO;
import com.budwk.app.sqfwDoc.codeGenerator.pdfGenerate.AbstractCustomerPdfCreateField;
import com.budwk.app.sqfwDoc.codeGeneratorV2.fileParam.PdfGenerateParam;
import com.budwk.app.sqfwV2.constants.ProblemConstant;
import com.budwk.app.sqfwV2.dto.dto.dayingRoad.DownFileTypesResVo;
import com.budwk.app.sqfwV2.dto.entity.SqfwProblemInfo;
import com.budwk.app.sqfwV2.dto.entity.SqfwShopsBaseInfo;
import com.budwk.app.sqfwV2.dto.shawenTown.SWTownProblemVo;
import com.budwk.app.sqfwV2.dto.shawenTown.ShawenTownSafetyPdfDTO;
import com.budwk.app.sqfwV2.dto.shawenTown.ShawenTownSafetyProblemVo;
import com.budwk.app.sqfwV2.dto.shawenTown.UpdateVisitPicturesVo;
import com.budwk.app.sqfwV2.enums.FileServiceConfigEnum;
import com.budwk.app.sqfwV2.service.ProblemInfoService;
import com.budwk.app.sqfwV2.service.ShopsBaseInfoService;
import com.budwk.app.sys.services.SysDictService;
import com.budwk.app.sys.vo.SysDictVO;
import com.budwk.app.util.DateUtils;
import com.budwk.app.util.StrUtil;
import com.budwk.app.util.poiUtils.CommonFormOfficeUtils;
import com.budwk.app.util.poiUtils.nutzBeanUtils.NutzIocUtils;
import com.budwk.starter.common.result.Result;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 沙文镇功能公共类
 */

@Slf4j
@IocBean
public class ShawenTownComponent {

    @Inject
    private ShopsBaseInfoService shopsBaseInfoService;
    @Inject
    private SqfwFormsummaryNewService sqfwFormsummaryNewService;

    public static final String FILL_TYPE = SupportBusinessTypeEnum.BATYUN_SAFE.getName();

    public static List<SqfwProblemInfo> getElecDefaultValues() {
        ProblemInfoService problemInfoService = NutzIocUtils.getBean(ProblemInfoService.class);
        return problemInfoService.listByCodes(List.of(ProblemConstant.BAIYUN_SAFETY_CHECK_ELEC_SEVEN, ProblemConstant.BAIYUN_SAFETY_CHECK_ELEC_FOUR));
    }

    public static SWTownProblemVo getElecProblemByNumber(List<SWTownProblemVo> list, String number) {
        return list.stream().filter(e -> e.getRiskCode().equals(number)).findFirst().get();
    }
    public static SWTownProblemVo initData(SqfwProblemInfo p) {
        SWTownProblemVo s = new SWTownProblemVo();
        s.setFields(p.getFields()).setKey(p.getDefaultValue()).setRiskDesc(p.getRiskDesc()).setRiskCode(String.valueOf(p.getRiskCode()));
        return s;
    }

    public static List<SWTownProblemVo> getSevenDefaults() {
        ProblemInfoService problemInfoService = NutzIocUtils.getBean(ProblemInfoService.class);
        List<SqfwProblemInfo> list = problemInfoService.findByCode(ProblemConstant.BAIYUN_SAFETY_CHECK_ELEC_SEVEN);
        List<SWTownProblemVo> datas = new ArrayList<>();
        for (SqfwProblemInfo p : list) {
            datas.add(initData(p));
        }
        return datas;
    }

    public static List<SWTownProblemVo> getHazardsDefaults() {
        ProblemInfoService problemInfoService = NutzIocUtils.getBean(ProblemInfoService.class);
        List<SqfwProblemInfo> list = problemInfoService.findByCode(ProblemConstant.HAZARDS_PROBLEMS);
        List<SWTownProblemVo> datas = new ArrayList<>();
        for (SqfwProblemInfo p : list) {
            datas.add(initData(p));
        }
        return datas;
    }

    public static List<SWTownProblemVo> getTwoDefaults() {
        ProblemInfoService problemInfoService = NutzIocUtils.getBean(ProblemInfoService.class);
        List<SqfwProblemInfo> list = problemInfoService.findByCode(ProblemConstant.BAIYUN_SAFETY_CHECK_ELEC_FOUR);
        // 取出编号为2和4的问题
        List<SqfwProblemInfo> infoList = list.stream().filter(e -> e.getRiskCode() == 2 || e.getRiskCode() == 4).collect(Collectors.toList());
        List<SWTownProblemVo> datas = new ArrayList<>();
        for (SqfwProblemInfo p : infoList) {
            datas.add(initData(p));
        }
        return datas;
    }

    public static List<SWTownProblemVo> getElecFourDefaults() {
        ProblemInfoService problemInfoService = NutzIocUtils.getBean(ProblemInfoService.class);
        List<SqfwProblemInfo> list = problemInfoService.findByCode(ProblemConstant.BAIYUN_SAFETY_CHECK_ELEC_FOUR);
        List<SWTownProblemVo> datas = new ArrayList<>();
        for (SqfwProblemInfo p : list) {
            datas.add(initData(p));
        }
        return datas;
    }

    /**
     * 解析业务代码提供的类
     * @param pdfDTO
     * @return
     */
    public static ShawenTownSafetyPdfDTO getShawenTownSafetyPdfDTO(PdfGenerateParam pdfDTO) {
        AbstractCustomerPdfCreateField field = pdfDTO.getAbstractCustomerPdfCreateField();
        if (field == null) {
            throw new AppException("参数对象不能为空！");
        }
        if (field instanceof ShawenTownSafetyPdfDTO) {
            ShawenTownSafetyPdfDTO roadPdfDTO = (ShawenTownSafetyPdfDTO) field;
            return roadPdfDTO;
        }
        throw new AppException("参数解析失败，请联系系统管理员！");
    }

    /**
     * 签名(excel方式签名)
     */
    public static void excelSignature(String checkedUnitLeader, String signName, Map<String, Object> paramMap) {
        paramMap.put("checkedUnitLeader", new ArrayList<>());
        paramMap.put("checkedUnitLeaderStr", "");
        if (StringUtils.isNotEmpty(checkedUnitLeader)) {
            paramMap.put("checkedUnitLeader", CommonFormOfficeUtils.addPictureToByteList(checkedUnitLeader, 1));
        } else {
            paramMap.put("checkedUnitLeaderStr", signName);
        }
    }

    public static void formatFillDate(ShawenTownSafetyPdfDTO pdfDTO, Map<String, Object> paramMap) {
        LocalDateTime fillDate = pdfDTO.getFillDate();
        paramMap.put("fillDate", LocalDateTimeUtil.format(fillDate, DatePattern.CHINESE_DATE_PATTERN));
    }

    public static List<Sqfw_formSummary_new> getSummaryList(SqfwExcelCreateCommonBO excelCreateParam) {
        List<SqfwExcelForSummaryBO> dataList = excelCreateParam.getDataList();
        if (dataList == null || dataList.size() == 0){
            return List.of();
        }
        // 排序 按照时间倒序排列
        List<Sqfw_formSummary_new> datas = dataList.stream().map(SqfwExcelForSummaryBO::getSqfwFormSummaryNew)
                .sorted(Comparator.comparing(Sqfw_formSummary_new::getCreateDate).reversed()).collect(Collectors.toList());
        return datas;
    }

    /**
     * 计算罚款金额
     */
    public static BigDecimal getPenaltyAmount(List<SWTownProblemVo> list, SWTownProblemVo fineOrNotEnum) {
        Optional<SWTownProblemVo> optioanl = list.stream().filter(e -> e.getFields().equals(fineOrNotEnum.getFields())).findFirst();
        if (optioanl.isPresent()) {
            SWTownProblemVo s = optioanl.get();
            return s.getPenaltyAmount();
        }
        return null;
    }


    public static void checkUpdateVisitPictures(UpdateVisitPicturesVo picturesVo) {
        if (picturesVo == null) {
            throw new AppException("参数对象不能为空！");
        }
        if (StringUtils.isEmpty(picturesVo.getId())) {
            throw new AppException("请求参数id不能为空！");
        }
    }

    public static List<byte[]> getImage(String image) {
        if (StringUtils.isEmpty(image)) {
            return null;
        }
        return CommonFormOfficeUtils.addPictureToByteList(image, 1);
    }

    public static void
    checkFormSummarysData(FileServiceConfigEnum serviceConfig, DownFileTypesResVo resVo, List<Sqfw_formSummary_new> formSummarys) {
        Class<?> service = serviceConfig.getService();
        if (service == null) {
            return;
        }
        BaseTemplateExcelGenerator basePdfGenerator = StrUtil.getNewClass(service);
        // 检查新数据
        List<Sqfw_formSummary_new> newList = basePdfGenerator.generateNewData(formSummarys);
        resVo.setHiveData(newList.size() > 0).setIds(newList.stream().map(Sqfw_formSummary_new::getId).collect(Collectors.toList()));
    }

    /**
     * @param code
     * @return
     */
    public static BaseTemplateExcelGenerator getService(String code) {
        FileServiceConfigEnum f = FileServiceConfigEnum.findByCode(SupportBusinessTypeEnum.BATYUN_SAFE.getName(), code);
        Class<?> service = f.getService();
        if (service == null) {
            return null;
        }
        BaseTemplateExcelGenerator baseTemplateExcelGenerator = StrUtil.getNewClass(service);
        return baseTemplateExcelGenerator;
    }

    public Result<?> listByConditionPlaceName(String placeName) {
        if (StringUtils.isEmpty(placeName)) {
            return Result.success();
        }
        List<SqfwShopsBaseInfo> shopsBaseInfos = shopsBaseInfoService.listByCondition("placeName", placeName);
        if (shopsBaseInfos.size() == 0) {
            return Result.success();
        }
        // 取出所有的商铺id
        List<String> shopIds = shopsBaseInfos.stream().map(SqfwShopsBaseInfo::getId).collect(Collectors.toList());
        List<Sqfw_formSummary_new> formSummaryNews = sqfwFormsummaryNewService.queryByShopIdsAndType(shopIds, FILL_TYPE);
        // 组装数据
        List<Sqfw_formSummary_new> results = new ArrayList<>();
        for (SqfwShopsBaseInfo baseInfo : shopsBaseInfos) {
            Optional<Sqfw_formSummary_new> optional = formSummaryNews.stream().filter(e -> e.getShopsBaseInfoId().equals(baseInfo.getId())).findFirst();
            if (optional.isPresent()) {
                Sqfw_formSummary_new summaryNew = optional.get();
                summaryNew.setShopsBaseInfoId(baseInfo.getId()).setShopsBaseInfo(baseInfo);
                results.add(summaryNew);
                continue;
            }
            ShawenTownSafetyPdfDTO pdfDTO = new ShawenTownSafetyPdfDTO();
            ShawenTownSafetyProblemVo sm = new ShawenTownSafetyProblemVo();
            sm.setPlaceName(baseInfo.getPlaceName())
                    .setKey(CommonConstants.TRUE)
                    .setMainBusinessScope(baseInfo.getMainBusinessScope())
                    .setLegalName(baseInfo.getOperator())
                    .setLegalMobile(baseInfo.getOperatorTelephone())
                    .setSocialCreditCode(baseInfo.getSocialCreditCode())
                    .setPlaceArea(baseInfo.getPlaceArea());
            pdfDTO.setSmallBusinessEstablishment(sm)
                    .setAddress(baseInfo.getAddress())
                    .setOperatorTelephone(baseInfo.getOperatorTelephone())
                    .setOperator(baseInfo.getOperator());
            Sqfw_formSummary_new summaryNew = new Sqfw_formSummary_new();
            summaryNew.setParamData(JSONObject.toJSONString(pdfDTO))
                    .setShopsBaseInfoId(baseInfo.getId())
                    .setShopsBaseInfo(baseInfo)
                    .setFillDate(baseInfo.getFillDate() != null ? DateUtils.toDateByLocalDateTime(baseInfo.getFillDate()) : DateUtil.parse(CommonConstants.WASTE_CREATE_TIME));
            results.add(summaryNew);
        }
        return Result.data(results);
    }

    public Result<?> listByConditionAddress(String address) {
        if (StringUtils.isEmpty(address)) {
            return Result.success();
        }
        // 1 先查询记录是否存在
        List<SqfwShopsBaseInfo> shopsBaseInfos = shopsBaseInfoService.listByCondition("address", address);
        if (CollectionUtil.isEmpty(shopsBaseInfos)) {
            return Result.data(Lists.newArrayList());
        }
        List<String> shopsIds = shopsBaseInfos.stream().map(SqfwShopsBaseInfo::getId).collect(Collectors.toList());
        List<Sqfw_formSummary_new> list = sqfwFormsummaryNewService.queryByShopIdsAndType(shopsIds, FILL_TYPE);
        // 存在商铺数据
        List<Sqfw_formSummary_new> results = new ArrayList<>();
        for (SqfwShopsBaseInfo baseInfo : shopsBaseInfos) {
            Optional<Sqfw_formSummary_new> optional = list.stream().filter(e -> e.getShopsBaseInfoId().equals(baseInfo.getId())).findFirst();
            if (optional.isPresent()) {
                Sqfw_formSummary_new summaryNew = optional.get();
                summaryNew.setShopsBaseInfoId(baseInfo.getId()).setShopsBaseInfo(baseInfo);
                results.add(summaryNew);
                continue;
            }
            ShawenTownSafetyPdfDTO pdfDTO = new ShawenTownSafetyPdfDTO();
            ShawenTownSafetyProblemVo sm = new ShawenTownSafetyProblemVo();
            sm.setPlaceName(baseInfo.getPlaceName())
                    .setKey(CommonConstants.TRUE)
                    .setMainBusinessScope(baseInfo.getMainBusinessScope())
                    .setLegalName(baseInfo.getOperator())
                    .setLegalMobile(baseInfo.getOperatorTelephone())
                    .setSocialCreditCode(baseInfo.getSocialCreditCode())
                    .setPlaceArea(baseInfo.getPlaceArea());
            pdfDTO.setSmallBusinessEstablishment(sm)
                    .setAddress(baseInfo.getAddress())
                    .setOperatorTelephone(baseInfo.getOperatorTelephone())
                    .setOperator(baseInfo.getOperator());
            Sqfw_formSummary_new summaryNew = new Sqfw_formSummary_new();
            summaryNew.setParamData(JSONObject.toJSONString(pdfDTO))
                    .setShopsBaseInfoId(baseInfo.getId())
                    .setShopsBaseInfo(baseInfo)
                    .setFillDate(baseInfo.getFillDate() != null ? DateUtils.toDateByLocalDateTime(baseInfo.getFillDate()) : DateUtil.parse(CommonConstants.WASTE_CREATE_TIME));
            results.add(summaryNew);
        }
        return Result.data(results);
    }

    public static List<DownFileTypesResVo> listDownFileTypes(String sqfwId) {
        SysDictService sysDictService = NutzIocUtils.getBean(SysDictService.class);
        SqfwFormsummaryNewService sqfwFormsummaryNewService = NutzIocUtils.getBean(SqfwFormsummaryNewService.class);
        // 1 获取所有字典数据
        List<SysDictVO> vos = sysDictService.listDictByCode(DictConstants.SHAWEN_EXCEL_COLLECTION);
        //2 按照社区服务id查询数据
        List<Sqfw_formSummary_new> list = sqfwFormsummaryNewService.queryBySqfwIdAndType(sqfwId, FILL_TYPE);
        // 检查数据是否可生成
        List<DownFileTypesResVo> results = new ArrayList<>();
        for (SysDictVO vo : vos) {
            getDownFileTypesResVo(results, list, vo);
        }
        // 排序(按照修改时间升序)
        List<DownFileTypesResVo> resVos = results.stream().sorted(Comparator.comparing(DownFileTypesResVo::getLocation)).collect(Collectors.toList());
        System.out.println("------------" + results.size());
        // 安全排查表pdf
        DownFileTypesResVo resVo = new DownFileTypesResVo();
        resVo.setFileName(DownLoadFileNameEnum.SHAWEN_INVESTIGATE_RENOVATE.getName() + ".pdf").
                setFileCode(DownLoadFileNameEnum.SHAWEN_INVESTIGATE_RENOVATE.getCode()).setHiveData(list.size() > 0)
                .setCreatedAt(System.currentTimeMillis())
                .setFileType("pdf");
        resVos.add(resVo);
        return resVos;
    }

    private static void getDownFileTypesResVo(List<DownFileTypesResVo> results, List<Sqfw_formSummary_new> list, SysDictVO vo) {
        DownFileTypesResVo resVo = new DownFileTypesResVo();
        BaseTemplateExcelGenerator service = getService(vo.getCode());
        List<Sqfw_formSummary_new> newList = service.generateNewData(list);
        resVo.setFileCode(vo.getCode()).setFileName(vo.getName())
                .setHiveData(newList.size() > 0)
                .setCreatedAt(vo.getCreatedAt())
                .setUpdateAt(vo.getUpdatedAt())
                .setFileType("excel")
                .setLocation(vo.getLocation());
        results.add(resVo);
    }
}
